/*
	This file is part of PropExtractor.

	AliceDecrypt is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	AliceDecrypt is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with PropExtractor. If not, see <http://www.gnu.org/licenses/>.
*/

#include "PETools.h"

namespace pe
{

	// ================================
	// Tools
	// ================================

	int CheckDirectory(const char* a_FilePath)
	{
		char* lastslash = strrchr((char*)a_FilePath, '\\');
		char filedir[_MAX_PATH];
		memset(filedir, 0, _MAX_PATH);
		strncat(filedir, a_FilePath, lastslash - a_FilePath + 1);

		ALICE_DEBUG("File directory: %s", filedir);

		// NOTE: for any cross platform dudes out there, this will be probably need to be fixed
		int success = SHCreateDirectoryExA(NULL, filedir, NULL);
		if (success != 0 && success != ERROR_ALREADY_EXISTS)
		{
			ALICE_PRINT("ERROR! Could not create directory. Try adding the working directory.");
			return -1;
		}

		return 0;
	}

	int GetPatternedPath(char* a_Target, size_t* a_Length, const char* a_Pattern, const char* a_Path, const char* a_WorkingDir, unsigned int a_Index)
	{
		memset(a_Target, 0, _MAX_PATH);

		char* lastslash = strrchr((char*)a_Path, '\\');
		if (!lastslash) 
		{ 
			lastslash = (char*)a_Path; 
		}
		else
		{
			lastslash++;
		}
		char* lastdot = strrchr((char*)a_Path, '.');

		char filename[256];
		memset(filename, 0, 256);
		strncpy(filename, lastslash, lastdot - lastslash);

		char command[256];
		const char* src = a_Pattern;
		char* dst = command;
		bool add = false;

		char workingdir[_MAX_PATH];
		if (!a_WorkingDir)
		{
			char dir[_MAX_PATH];
			GetModuleFileNameA(NULL, dir, _MAX_PATH);
			char* lastslash = strrchr(dir, '\\');
			strncpy(workingdir, dir, lastslash - dir + 1);
			workingdir[lastslash - dir + 1] = 0;
		}
		else
		{
			strcpy(workingdir, a_WorkingDir);
		}

		for (size_t i = 0; i < strlen(a_Pattern); i++)
		{
			if (*src == '%')
			{
				if (add)
				{
					*dst++ = 0;
					if (!strcmp(command, "workingdir"))
					{
						strcat(a_Target, workingdir);
					}
					else if (!strcmp(command, "dir"))
					{
						strncat(a_Target, a_Path, lastslash - a_Path + 1);
					}
					else if (!strcmp(command, "name"))
					{
						strcat(a_Target, filename);
					}
					else if (!strcmp(command, "ext"))
					{
						strcat(a_Target, lastdot);
					}
					else if (!strcmp(command, "index"))
					{
						char number[256];
						_itoa(a_Index, number, 10);
						strcat(a_Target, number);
					}

					dst = command;
					add = false;
				}
				else
				{
					add = true;
				}

				src++;
				continue;
			}

			if (add)
			{
				*dst++ = *src;
			}
			else
			{
				strncat(a_Target, src, 1);
			}
			src++;
		}

		*a_Length = strlen(a_Target);

		return 0;
	}

	int WriteTGA(const char* a_FilePath, unsigned int a_Width, unsigned int a_Height, byte* a_Data)
	{
		FILE* handle = fopen(a_FilePath, "w+b");
		if (!handle) { return -1; }

		byte id = 0;			                fwrite(&id, 1, 1, handle);
		byte colormap = 0;		                fwrite(&colormap, 1, 1, handle);
		byte compression = 2;                   fwrite(&compression, 1, 1, handle);

		word colormap_offset = 0;               fwrite(&colormap_offset, 1, 1, handle);
		word colormap_length = 0;               fwrite(&colormap_length, 1, 1, handle);
		byte colormap_bpp = 0;                  fwrite(&colormap_bpp, 1, 1, handle);

		word padding = 0;                       fwrite(&padding, 2, 1, handle);

		word origin_x = 0;                      fwrite(&origin_x, 2, 1, handle);
		word origin_y = 0;                      fwrite(&origin_y, 2, 1, handle);

		word width = (word)a_Width;             fwrite(&width, 2, 1, handle);
		word height = (word)a_Height;           fwrite(&height, 2, 1, handle);

		byte depth = 24;                        fwrite(&depth, 1, 1, handle);

		byte img_descriptor = 0;                fwrite(&img_descriptor, 1, 1, handle);

		// write to the file

		for (unsigned int y = a_Height; y > 0; y--)
		{
			byte* data = a_Data + ((y - 1) * a_Width * 3);
			fwrite(data, 3, a_Width, handle);
		}

		fclose(handle);

		//ShellExecuteA(NULL, NULL, a_FilePath, NULL, NULL, SW_SHOW);

		return 0;
	}

	int ReadBytes(void* a_Target, unsigned int a_ElementSize, unsigned int a_Amount, byte* a_Source)
	{
		byte* dst = (byte*)a_Target;
		byte* src = a_Source;

		for (unsigned int i = 0; i < a_Amount; i++)
		{
			for (unsigned int j = 0; j < a_ElementSize; j++)
			{
				dst[j] = src[j];
			}

			dst += a_ElementSize;
			src += a_ElementSize;
		}

		return a_ElementSize * a_Amount;
	}

}